package com.example.origin.resttemplate.config;

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.UUID;

/**
 * @author yutao.zhang
 * @create 2022-07-14 14:29
 **/
@Configuration
public class RestTemplateConfiguration {

    @Value("${resttemplate.config.connectTimeout:10000}")
    private int connectTimeout;
    @Value("${resttemplate.config.readTimeout:30000}")
    private int readTimeout;


    @Bean
    public RestTemplate restTemplate() {
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//        defaultMaxPerRoute 是针对每个单独路由的并发连接限制，而 maxTotal 是对所有路由共享的连接池的总体大小限制。
//        一个形象的比喻是，defaultMaxPerRoute 类似于每条车道上的车辆限流，而 maxTotal 是整个停车场能容纳的车辆总数。
        httpClientBuilder.setMaxConnTotal(100);
        httpClientBuilder.setMaxConnPerRoute(100);
        httpClientBuilder.disableAutomaticRetries();
        httpClientBuilder.disableRedirectHandling();
        httpClientBuilder.disableContentCompression();

        CloseableHttpClient httpClient = httpClientBuilder.useSystemProperties().build();
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        httpRequestFactory.setConnectTimeout(connectTimeout);
        httpRequestFactory.setReadTimeout(readTimeout);
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        restTemplate.setInterceptors(Collections.singletonList((httpRequest, bytes, clientHttpRequestExecution) -> {
            HttpHeaders headers = httpRequest.getHeaders();
            headers.setAccept(Collections.singletonList(MediaType.ALL));
            headers.add("uuid", UUID.randomUUID().toString());
            return clientHttpRequestExecution.execute(httpRequest, bytes);
        }));
        restTemplate.getMessageConverters().stream().filter(e -> e instanceof StringHttpMessageConverter).forEach(e -> ((StringHttpMessageConverter) e).setDefaultCharset(StandardCharsets.UTF_8));
        return restTemplate;
    }
}
